package cos.gui;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;

import com.qotsa.exception.InvalidHandle;

import cos.entity.LyricsResponse;
import cos.entity.Song;
import cos.parser.ParsingManager;
import cos.titlegetter.TitleGetterManager;
import cos.utils.GoogleTranslationGetter;

public class LyricsPanel extends JPanel {

	private static final long serialVersionUID = 1L;
	private static final String NOTHING_TO_SEE = "Nothing to see here, move along...";
	private static final String LOADED_FROM = "Loaded from: ";

	private final JLabel songNameLabel = new JLabel("");
	private final JTextArea lyricsTextArea = new JTextArea("");
	private final JButton translateButton = new JButton("Translate");
	private JPanel southAreaPanel = new JPanel(new BorderLayout());
	private JPanel infoPanel = new JPanel(new BorderLayout());
	private final JLabel loadedFrom = new JLabel("");
	private JPanel translationPanel = new JPanel(new BorderLayout());
	private final JLabel translationLabel = new JLabel(" ");
	private JLabel procLabel;
	private JScrollPane scrollPanePlain;

	private Song song = new Song("", "");
	private ParsingManager parsingManager = new ParsingManager();
	private final TitleGetterManager titleGetterManager = new TitleGetterManager();

	public LyricsPanel() {
		setLayout(new BorderLayout());

		// song name area
		songNameLabel.setHorizontalAlignment(SwingConstants.CENTER);
		songNameLabel.setFont(new Font("Consolas", 5, 13));
		add(songNameLabel, BorderLayout.NORTH);

		// lyrics area
		lyricsTextArea.setEditable(false);
		lyricsTextArea.setFont(new Font("Consolas", 5, 12));
		lyricsTextArea.setLineWrap(true);
		lyricsTextArea.setWrapStyleWord(true);
		lyricsTextArea.addMouseListener(new Mouse_Handler());

		infoPanel.add(new NavigationPanel(), BorderLayout.WEST);
		infoPanel.add(loadedFrom);

		add(southAreaPanel, BorderLayout.SOUTH);
		southAreaPanel.add(translationPanel, BorderLayout.NORTH);
		southAreaPanel.add(infoPanel, BorderLayout.SOUTH);

		JPanel translationRight = new JPanel(new BorderLayout());
		// translation area
		translationRight.add(new TranslationDirectionComboBox(),
				BorderLayout.WEST);
		translationRight.add(translateButton, BorderLayout.EAST);
		translationPanel.add(translationRight, BorderLayout.EAST);
		translationPanel.add(translationLabel, BorderLayout.WEST);
		translationLabel.setFont(new Font("Consolas", 5, 13));

		translateButton.addActionListener(new Button_Handler());
		translateButton.setIcon(new ImageIcon(Toolkit.getDefaultToolkit()
				.createImage("img/btn/chat-active.png")));

		Icon procImage = new ImageIcon(Toolkit.getDefaultToolkit().createImage(
				"img/processing.gif"));
		procLabel = new JLabel(procImage);
		infoPanel.add(procLabel, BorderLayout.EAST);
		procLabel.setVisible(false);

		// scroll & text area
		scrollPanePlain = new JScrollPane(lyricsTextArea);
		add(scrollPanePlain);

		/**
		 * thread, that every 0.5 seconds checks, if song is changes
		 */
		new Thread(new Runnable() {
			public void run() {
				while (true) {
					try {
						reload();
					} catch (InvalidHandle e1) {
						lyricsTextArea
								.setText("Winamp isn't running. Please start winamp.");
						songNameLabel.setText("");
						song = new Song("", "");
					}
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
					}
				}
			}
		}).start();
	}

	public boolean showHideInfoPanel() {
		boolean b = infoPanel.isVisible();
		infoPanel.setVisible(!b);
		return b;
	}

	public boolean showHideTranslationPanel() {
		boolean b = translationPanel.isVisible();
		translationPanel.setVisible(!b);
		return b;
	}

	/**
	 * check if song is new and if its true, try to reload page with a new
	 * lyrics
	 * 
	 * @throws InvalidHandle
	 */
	private void reload() throws InvalidHandle {
		Song newSong = titleGetterManager.getCurrentSongTitle();

		// if song is new
		if (newSong != null && !song.equals(newSong)) {
			long now = System.currentTimeMillis();

			procLabel.setVisible(true);
			song = newSong;

			// get new song's lyrics
			LyricsResponse resp = parsingManager.getLyrics(song);
			String out = NOTHING_TO_SEE;
			String loaded = "";
			if (resp != null) {
				String yoba = resp.getLyrics();
				if (yoba != null && !yoba.isEmpty()) {
					out = yoba;
					loaded = LOADED_FROM + resp.getParserName().getName()
							+ " in "
							+ ((System.currentTimeMillis() - now) / 1000.)
							+ " sec.";
				}
			}

			loadedFrom.setText(loaded);
			lyricsTextArea.setText(out);
			songNameLabel.setText(song.getArtist() + " - " + song.getTitle());

			// puts scroller up
			scrollPanePlain.getVerticalScrollBar().setValue(0);

			// hide "processing" image
			procLabel.setVisible(false);
		}
	}

	/**
	 * try to get translation of the selected text
	 */
	private void translate() {
		String s = lyricsTextArea.getSelectedText();
		if (s != null) {
			String gt = GoogleTranslationGetter.translate(s);
			if (gt != null) {
				translationLabel.setText(gt);
			}
		}
	}

	class Button_Handler implements ActionListener {
		public void actionPerformed(ActionEvent evt) {
			translate();
		}
	}

	class Mouse_Handler implements MouseListener {
		JPopupMenu popup = new JPopupMenu();
		JMenuItem item = new JMenuItem("Copy", new ImageIcon(Toolkit
				.getDefaultToolkit().createImage("img/btn/copy.png")));

		public Mouse_Handler() {
			popup.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					lyricsTextArea.copy();
				}
			});
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 1)
				translate();
			else if (e.getButton() == MouseEvent.BUTTON3) {
				popup.show(LyricsPanel.this, e.getX(), e.getY() + 10);
			}

		}

		@Override
		public void mousePressed(MouseEvent e) {
		}

		@Override
		public void mouseReleased(MouseEvent e) {
		}

		@Override
		public void mouseEntered(MouseEvent e) {
		}

		@Override
		public void mouseExited(MouseEvent e) {
		}

	}
}
